﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web.UI.WebControls;
using CH.FourBoards.LagerWalti.FrontEnd.View.Util;
using CH.FourBoards.LagerWalti.Service.DTOs.MasterData;
using CH.FourBoards.LagerWalti.Service.DTOs.Warehouse;
using CH.FourBoards.LagerWalti.Service.Services;
using CH.FourBoards.LagerWalti.WebFrontEnd.View.Generic.RecordSetView;

namespace CH.FourBoards.LagerWalti.WebFrontEnd.View.Warehouse
{
    public class InventoryView : RecordSetBase
    {
        private InventoryCatalog _inventory;

        protected enum Views
        {
            All = 1, Available = 2, OutOfStock = 3
        }

        protected Views View { get; set; }

        protected override void OnLoad(EventArgs e)
        {
            SwitchView();
            base.OnLoad(e);
        }

        private void SwitchView()
        {
            View = Views.All;
            if (Request["view"] == null) {
                return;
            }
            View = (Views) Enum.Parse(typeof(Views), Request["view"], true);
        }

        protected override DataTable CreateMenuSource()
        {
            // prepare table
            var table = new DataTable();
            table.Columns.Add("Attributes");
            table.Columns.Add("RecordUrl");
            table.Columns.Add("Text");

            // add items
            AddViewMenuItem(table, Views.All, "All");
            AddViewMenuItem(table, Views.Available, "Available");
            AddViewMenuItem(table, Views.OutOfStock, "OutOfStock");

            return table;
        }

        private void AddViewMenuItem(DataTable table, Views view, string text)
        {
            var row = table.NewRow();
            row["RecordUrl"] = ApplicationRoot + CreateMenuLink("view", view.ToString());
            row["Text"] = text;
            row["Attributes"] = string.Empty;
            table.Rows.Add(row);
        }

        protected DataTable CreateItemSource(InventoryCatalog inventory, int categoryId)
        {
            // filter on category
            var category = inventory.Categories.First(c => c.Id == categoryId);
            var items = Filter(inventory, category);

            // prepare table
            var table = new DataTable();
            table.Columns.Add("RecordUrl");
            table.Columns.Add("Product");
            table.Columns.Add("Stock");
            table.Columns.Add("RowAttributes");


            // iterate transactions
            foreach (var item in items) {
                // select data
                var product = inventory.Products.First(p => p.Id == item.ProductId);

                // add data to row
                var row = table.NewRow();
                row["RecordUrl"] = "#"; // ApplicationRoot + new ExecutionView().CreateExecutionLink(execution.ID);
                row["Product"] = product.Name;
                row["Stock"] = item.Stock;
                row["RowAttributes"] = CreateRowAttributes(item);

                table.Rows.Add(row);
            }

            return table;
        }

        protected override void OnTableRowCreated(RepeaterItem repeaterItem, DataRowView row)
        {
            // retrieve category
            var categoryId = int.Parse((string) row.Row["CategoryId"]);

            // create nested source
            var repeater = (Repeater) repeaterItem.FindControl("ItemRepeater");
            repeater.DataSource = CreateItemSource(_inventory, categoryId);
            repeater.DataBind();
        }

        private IEnumerable<InventoryItem> Filter(InventoryCatalog inventory, CategoryDTO category)
        {
            return inventory.Items.Where(i => _inventory.Products.First(p => i.ProductId == p.Id).CategoryId == category.Id);
        }

        protected override DataTable CreateRecordSetSource()
        {
            // prepare table
            var table = new DataTable();
            table.Columns.Add("CategoryId");
            table.Columns.Add("CategoryName");

            // load  data
            var service = new WarehouseService();
            switch (View) {
                case Views.Available:
                    _inventory = service.ListAvailableInventory();
                    break;
                case Views.OutOfStock:
                    _inventory = service.ListOutOfStock();
                    break;
                default:
                    _inventory = service.ListInventory();
                    break;
            }

            // iterate categories
            foreach (var category in _inventory.Categories) {

                // check for empty category
                var items = Filter(_inventory, category);
                if (!items.Any()) {
                    continue;
                }

                // add data to row
                var row = table.NewRow();
                row["CategoryId"] = category.Id;
                row["CategoryName"] = category.Name;
                table.Rows.Add(row);
            }

            return table;
        }

        private string CreateRowAttributes(InventoryItem item)
        {
            var attributes = new Dictionary<string, string>();

            if (item.Stock <= 0) {
                attributes["class"] = "danger";
            } else if (item.Stock > 5) {
                attributes["class"] = "success";
            } else {
                attributes["class"] = "warning";
            }

            return new ContentRenderer().CreateAttributeString(attributes);
        }

    }
}